package jwts

import (
	"time"

	"github.com/golang-jwt/jwt/v4"
)

// JWT配置
type JwtConf struct {
	AccessSecret string
	AccessExpire int64
	RefreshAfter int64
}

// JWT用户声明
type Claims struct {
	Id       int64  `json:"id"`
	Uuid     string `json:"uuid"`
	Username string `json:"username"`
	jwt.RegisteredClaims
}

// 生成JWT令牌
func GenerateToken(jwtConf JwtConf, userId int64, uuid, username string) (string, int64, int64, error) {
	now := time.Now().Unix()
	accessExpire := now + jwtConf.AccessExpire
	refreshAfter := now + jwtConf.RefreshAfter

	claims := Claims{
		Id:       userId,
		Uuid:     uuid,
		Username: username,
		RegisteredClaims: jwt.RegisteredClaims{
			ExpiresAt: jwt.NewNumericDate(time.Unix(accessExpire, 0)),
			IssuedAt:  jwt.NewNumericDate(time.Now()),
			NotBefore: jwt.NewNumericDate(time.Now()),
		},
	}

	token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
	tokenString, err := token.SignedString([]byte(jwtConf.AccessSecret))
	if err != nil {
		return "", 0, 0, err
	}

	return tokenString, accessExpire, refreshAfter, nil
}

// 解析JWT令牌
func ParseToken(tokenString string, secret string) (*Claims, error) {
	token, err := jwt.ParseWithClaims(tokenString, &Claims{}, func(token *jwt.Token) (interface{}, error) {
		return []byte(secret), nil
	})

	if err != nil {
		return nil, err
	}

	if claims, ok := token.Claims.(*Claims); ok && token.Valid {
		return claims, nil
	}

	return nil, jwt.ErrSignatureInvalid
}
